/**
 * 客户端测试物品购买和背包查询功能脚本
 * 专注于测试：物品购买(1249)、背包查询(1476)
 */

const http = require('http');
const WebSocket = require('ws');

// 测试配置
const CONFIG = {
    server: {
        host: 'localhost',
        port: 3000,
        protocol: 'http'
    },

    // 测试用户信息
    testUser: {
        mobile: '17091271111',
        password: '123456',
        passwordHash: 'e10adc3949ba59abbe56e057f20f883e' // 123456的SHA256
    },

    // 测试角色信息
    testCharacter: {
        name: '测试角色',
        sex: 1, // 1:男, 0:女
        roleType: 1, // 1:武士, 2:文人, 3:异师
        headIndex: 2
    }
};

class ItemPurchaseTester {
    constructor() {
        this.token = null;
        this.userId = null;
        this.ws = null;
        this.characters = [];
        this.selectedCharacter = null;
        this.testResults = [];
        this.inventory = [];
    }

    // 运行完整测试流程
    async runTest() {
        console.log('🚀 开始客户端物品购买和背包查询功能测试...\n');
        console.log('测试目标：HTTP登录 → WebSocket连接 → 选择角色 → 测试物品购买 → 测试背包查询\n');

        try {
            // 1. HTTP登录
            await this.testHttpLogin();

            // 2. 建立WebSocket连接
            await this.testWebSocketConnection();

            // 3. 查询角色列表
            await this.testQueryCharacters();

            // 4. 如果没有角色，先创建角色
            if (this.characters.length === 0) {
                await this.testCreateCharacter();
                // 重新查询角色列表
                await this.testQueryCharacters();
            }

            // 5. 选择角色
            await this.testSelectCharacter();

            // 6. 测试物品购买 (1249)
            await this.testItemPurchase();

            // 7. 测试背包查询 (1476)
            await this.testInventoryQuery();

            // 8. 验证购买结果
            await this.validatePurchaseResults();

            // 9. 断开连接
            await this.testDisconnect();

            // 输出测试结果
            this.printTestResults();

        } catch (error) {
            console.error('❌ 测试过程中发生错误:', error.message);
            this.addTestResult('整体测试', false, error.message);
        }
    }

    // 1. HTTP登录测试
    async testHttpLogin() {
        console.log('🔐 步骤1: HTTP登录测试...');

        try {
            // 首先尝试注册用户（如果不存在）
            await this.registerUser();

            // 登录用户
            const loginData = await this.loginUser();
            this.token = loginData.token;
            this.userId = loginData.userId;

            console.log(`✅ 登录成功: userId=${this.userId}, token=${this.token.substring(0, 10)}...`);
            this.addTestResult('HTTP登录', true, `用户ID: ${this.userId}`);

        } catch (error) {
            console.error('❌ 登录失败:', error.message);
            this.addTestResult('HTTP登录', false, error.message);
            throw error;
        }
    }

    // 注册用户
    async registerUser() {
        return new Promise((resolve, reject) => {
            const postData = JSON.stringify({
                mobile: CONFIG.testUser.mobile,
                pwd: CONFIG.testUser.passwordHash
            });

            const options = {
                hostname: CONFIG.server.host,
                port: CONFIG.server.port,
                path: '/user-service/user/register',
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Content-Length': Buffer.byteLength(postData)
                }
            };

            const req = http.request(options, (res) => {
                let data = '';
                res.on('data', (chunk) => {
                    data += chunk;
                });
                res.on('end', () => {
                    try {
                        const result = JSON.parse(data);
                        console.log('📝 用户注册结果:', result);
                        resolve(result);
                    } catch (error) {
                        reject(new Error('注册响应解析失败: ' + error.message));
                    }
                });
            });

            req.on('error', (error) => {
                reject(new Error('注册请求失败: ' + error.message));
            });

            req.write(postData);
            req.end();
        });
    }

    // 登录用户
    async loginUser() {
        return new Promise((resolve, reject) => {
            const postData = JSON.stringify({
                mobile: CONFIG.testUser.mobile,
                pwd: CONFIG.testUser.passwordHash
            });

            const options = {
                hostname: CONFIG.server.host,
                port: CONFIG.server.port,
                path: '/user-service/user/login',
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Content-Length': Buffer.byteLength(postData)
                }
            };

            const req = http.request(options, (res) => {
                let data = '';
                res.on('data', (chunk) => {
                    data += chunk;
                });
                res.on('end', () => {
                    try {
                        const result = JSON.parse(data);
                        if (result.code === 0 && result.data) {
                            // 适配不同的token字段名
                            const token = result.data.accessToken || result.data.token;
                            const userId = result.data.userId;

                            if (token && userId) {
                                resolve({
                                    token: token,
                                    userId: userId
                                });
                            } else {
                                reject(new Error(`登录失败: 缺少token或userId - ${JSON.stringify(result)}`));
                            }
                        } else {
                            reject(new Error(`登录失败: ${JSON.stringify(result)}`));
                        }
                    } catch (error) {
                        reject(new Error('登录响应解析失败: ' + error.message));
                    }
                });
            });

            req.on('error', (error) => {
                reject(new Error('登录请求失败: ' + error.message));
            });

            req.write(postData);
            req.end();
        });
    }

    // 2. WebSocket连接测试
    async testWebSocketConnection() {
        console.log('\n🔌 步骤2: WebSocket连接测试...');

        return new Promise((resolve, reject) => {
            const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${this.token}`;
            console.log(`🔗 连接WebSocket: ${wsUrl}`);

            this.ws = new WebSocket(wsUrl);

            this.ws.on('open', () => {
                console.log('✅ WebSocket连接成功');
                this.addTestResult('WebSocket连接', true, '连接建立成功');
                resolve();
            });

            this.ws.on('error', (error) => {
                console.error('❌ WebSocket连接失败:', error.message);
                this.addTestResult('WebSocket连接', false, error.message);
                reject(error);
            });

            this.ws.on('close', () => {
                console.log('🔌 WebSocket连接已关闭');
            });
        });
    }

    // 3. 查询角色列表
    async testQueryCharacters() {
        console.log('\n📋 步骤3: 查询角色列表...');

        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            this.addTestResult('查询角色列表', false, 'WebSocket未连接');
            return;
        }

        return new Promise((resolve) => {
            let responseReceived = false;

            // 设置响应监听器
            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 3) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        console.log('📨 收到消息:', JSON.stringify(message, null, 2));

                        if (message.roleList && Array.isArray(message.roleList)) {
                            this.characters = message.roleList;
                            console.log(`📋 获取到${this.characters.length}个角色`);
                            console.log('✅ 查询成功，共' + this.characters.length + '个角色');
                            this.addTestResult('查询角色列表', true, `获取${this.characters.length}个角色`);
                        } else {
                            console.log('❌ 角色列表数据格式错误');
                            this.addTestResult('查询角色列表', false, '数据格式错误');
                        }
                        resolve();
                    }
                } catch (error) {
                    console.error('❌ 角色列表响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('查询角色列表', false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);

            // 发送查询角色列表请求
            const requestData = { c: 3, d: {} };
            console.log(`📤 发送查询角色列表请求:`, JSON.stringify(requestData, null, 2));
            this.ws.send(JSON.stringify(requestData));

            // 设置超时
            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('查询角色列表', false, '请求超时');
                    resolve();
                }
            }, 10000);
        });
    }

    // 4. 创建角色
    async testCreateCharacter() {
        console.log('\n👤 步骤4: 创建角色...');

        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            this.addTestResult('创建角色', false, 'WebSocket未连接');
            return;
        }

        return new Promise((resolve) => {
            let responseReceived = false;

            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 2) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        if (message.code === 0) {
                            console.log('✅ 角色创建成功');
                            this.addTestResult('创建角色', true, '角色创建成功');
                        } else {
                            console.log(`❌ 角色创建失败: ${message.msg || '未知错误'}`);
                            this.addTestResult('创建角色', false, message.msg || '创建失败');
                        }
                        resolve();
                    }
                } catch (error) {
                    console.error('❌ 角色创建响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('创建角色', false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);

            const requestData = {
                c: 2,
                d: {
                    name: CONFIG.testCharacter.name,
                    sex: CONFIG.testCharacter.sex,
                    roleType: CONFIG.testCharacter.roleType,
                    headIndex: CONFIG.testCharacter.headIndex
                }
            };

            console.log(`📤 发送创建角色请求:`, JSON.stringify(requestData, null, 2));
            this.ws.send(JSON.stringify(requestData));

            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('创建角色', false, '请求超时');
                    resolve();
                }
            }, 10000);
        });
    }

    // 5. 选择角色
    async testSelectCharacter() {
        console.log('\n🎯 步骤5: 选择角色...');

        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            this.addTestResult('选择角色', false, 'WebSocket未连接');
            return;
        }

        if (this.characters.length === 0) {
            console.log('❌ 没有可选择的角色');
            this.addTestResult('选择角色', false, '没有角色');
            return;
        }

        // 选择第一个角色
        this.selectedCharacter = this.characters[0];
        console.log(`🎯 选择角色: ${this.selectedCharacter.name} (ID: ${this.selectedCharacter.id})`);

        return new Promise((resolve) => {
            let responseReceived = false;

            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 4) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        if (message.code === 0) {
                            console.log('🎯 角色选择成功');
                            console.log('✅ 角色选择成功: ' + this.selectedCharacter.name + ' (ID: ' + this.selectedCharacter.id + ')');
                            this.addTestResult('选择角色', true, `选择角色: ${this.selectedCharacter.name}`);

                            // 等待服务器发送背包数据
                            setTimeout(() => {
                                resolve();
                            }, 2000);
                        } else {
                            console.log(`❌ 角色选择失败: ${message.msg || '未知错误'}`);
                            this.addTestResult('选择角色', false, message.msg || '选择失败');
                            resolve();
                        }
                    }
                } catch (error) {
                    console.error('❌ 角色选择响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('选择角色', false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);

            const requestData = {
                c: 4,
                d: { characterId: this.selectedCharacter.id }
            };

            console.log(`📤 发送选择角色请求:`, JSON.stringify(requestData, null, 2));
            this.ws.send(JSON.stringify(requestData));

            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('选择角色', false, '请求超时');
                    resolve();
                }
            }, 10000);
        });
    }

    // 6. 测试物品购买 (1249)
    async testItemPurchase() {
        console.log('\n🛒 步骤6: 测试物品购买(1249)...');

        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            this.addTestResult('物品购买测试', false, 'WebSocket未连接');
            return;
        }

        return new Promise((resolve) => {
            let responseReceived = false;

            // 设置响应监听器
            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 1249) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        console.log('📨 收到购买响应:', JSON.stringify(message, null, 2));

                        if (message.code === 0) {
                            console.log('✅ 物品购买成功');
                            console.log(`🛒 购买结果: ${message.data}`);
                            this.addTestResult('物品购买测试', true, `购买成功: ${message.data}`);
                        } else {
                            console.log(`❌ 物品购买失败: ${message.msg || '未知错误'}`);
                            this.addTestResult('物品购买测试', false, message.msg || '购买失败');
                        }
                        resolve();
                    }
                } catch (error) {
                    console.error('❌ 物品购买响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('物品购买测试', false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);

            // 发送1249请求 - 购买三黄丸
            const requestData = {
                c: 1249,
                d: {
                    goodsId: "7",      // 三黄丸
                    count: 1,          // 购买数量
                    silverType: 0,     // 银币类型
                    retType: 0         // 返回类型
                }
            };

            console.log(`📤 发送物品购买请求:`, JSON.stringify(requestData, null, 2));
            this.ws.send(JSON.stringify(requestData));

            // 设置超时
            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('物品购买测试', false, '请求超时');
                    resolve();
                }
            }, 10000);
        });
    }

    // 7. 测试背包查询 (1476)
    async testInventoryQuery() {
        console.log('\n🎒 步骤7: 测试背包查询(1476)...');

        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            this.addTestResult('背包查询测试', false, 'WebSocket未连接');
            return;
        }

        return new Promise((resolve) => {
            let responseReceived = false;

            // 设置响应监听器
            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    // 监听多个可能的背包查询响应
                    if (message.act_id === 1425 || message.act_id === 1416 || message.act_id === 1476) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        console.log('📨 收到背包查询响应:', JSON.stringify(message, null, 2));

                        if (message.code === 0) {
                            console.log('✅ 背包查询成功');
                            console.log(`🎒 背包物品数量: ${message.sum || 0}`);
                            console.log(`📋 当前页物品: ${message.list ? message.list.length : 0}个`);

                            // 保存背包数据
                            this.inventory = message.list || [];

                            // 验证基础数据结构
                            if (message.list && Array.isArray(message.list)) {
                                console.log('✅ 背包数据结构验证通过');
                                this.addTestResult('背包查询测试', true, `获取${message.list.length}个物品`);

                                // 显示物品列表
                                if (message.list.length > 0) {
                                    console.log('📋 物品列表:');
                                    message.list.forEach((item, index) => {
                                        console.log(`  ${index + 1}. ${item.name} (数量:${item.num}, 类型:${item.type})`);
                                    });
                                }
                            } else if (message.data === null) {
                                console.log('⚠️ 背包查询返回null，可能是指令格式问题');
                                this.addTestResult('背包查询测试', false, '返回数据为null');
                            } else {
                                console.log('❌ 背包数据结构验证失败');
                                this.addTestResult('背包查询测试', false, '数据结构错误');
                            }
                        } else {
                            console.log(`❌ 背包查询失败: ${message.msg || '未知错误'}`);
                            this.addTestResult('背包查询测试', false, message.msg || '查询失败');
                        }
                        resolve();
                    }
                } catch (error) {
                    console.error('❌ 背包查询响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('背包查询测试', false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);

            // 发送1476请求 - 查询背包
            const requestData = {
                c: 1476,
                d: {}
            };

            console.log(`📤 发送背包查询请求:`, JSON.stringify(requestData, null, 2));
            this.ws.send(JSON.stringify(requestData));

            // 设置超时
            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('背包查询测试', false, '请求超时');
                    resolve();
                }
            }, 10000);
        });
    }

    // 8. 验证购买结果
    async validatePurchaseResults() {
        console.log('\n🔍 步骤8: 验证购买结果...');

        // 查找三黄丸
        const sanhuangwan = this.inventory.find(item => item.name === '三黄丸');

        if (sanhuangwan) {
            console.log(`✅ 找到三黄丸: 数量 ${sanhuangwan.num}`);
            this.addTestResult('购买结果验证', true, `三黄丸数量: ${sanhuangwan.num}`);
        } else {
            console.log('❌ 未找到三黄丸');
            this.addTestResult('购买结果验证', false, '未找到三黄丸');
        }

        // 验证背包数据结构
        let validItems = 0;
        this.inventory.forEach((item, index) => {
            const validation = this.validateItemData(item, index);
            if (validation.isValid) {
                validItems++;
            }
        });

        console.log(`📊 物品数据验证结果: ${validItems}/${this.inventory.length} 个物品通过验证`);

        if (validItems === this.inventory.length) {
            console.log('✅ 所有物品数据结构验证通过');
        } else {
            console.log(`⚠️ 部分数据结构验证失败`);
        }
    }

    // 验证物品数据
    validateItemData(item, index) {
        const requiredFields = ['id', 'name', 'num', 'type'];

        const missingFields = [];
        const invalidFields = [];

        // 检查必需字段
        requiredFields.forEach(field => {
            if (!(field in item)) {
                missingFields.push(field);
            }
        });

        // 检查字段类型和值
        if (item.id && typeof item.id !== 'number') {
            invalidFields.push('id应为数字');
        }
        if (item.num && typeof item.num !== 'number') {
            invalidFields.push('num应为数字');
        }
        if (item.type && typeof item.type !== 'number') {
            invalidFields.push('type应为数字');
        }

        const isValid = missingFields.length === 0 && invalidFields.length === 0;

        if (!isValid) {
            console.log(`❌ 物品${index + 1}验证失败:`, {
                missing: missingFields,
                invalid: invalidFields
            });
        }

        return { isValid, missingFields, invalidFields };
    }

    // 9. 断开连接
    async testDisconnect() {
        console.log('\n🔌 步骤9: 断开WebSocket连接...');

        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.ws.close();
            console.log('✅ 连接已断开');
            this.addTestResult('断开连接', true, '连接已断开');
        } else {
            console.log('⚠️ 连接已断开或未连接');
            this.addTestResult('断开连接', false, '连接已断开或未连接');
        }
    }

    // 添加测试结果
    addTestResult(testName, success, message) {
        this.testResults.push({
            name: testName,
            success,
            message,
            timestamp: new Date().toISOString()
        });
    }

    // 输出测试结果
    printTestResults() {
        console.log('\n📊 测试结果汇总:');
        console.log('==================================================');

        this.testResults.forEach((result, index) => {
            const status = result.success ? '✅' : '❌';
            console.log(`${index + 1}. ${status} ${result.name}: ${result.message}`);
        });

        console.log('==================================================');

        const successCount = this.testResults.filter(r => r.success).length;
        const totalCount = this.testResults.length;

        console.log(`总计: ${successCount}/${totalCount} 项测试通过`);

        if (successCount === totalCount) {
            console.log('🎉 所有测试通过！');
        } else {
            console.log('⚠️ 部分测试失败');
        }

        console.log('\n🎒 背包数据结构分析:');
        console.log('==================================================');
        console.log(`总物品数: ${this.inventory.length}`);
        if (this.inventory.length > 0) {
            console.log('示例物品字段:');
            const sampleItem = this.inventory[0];
            Object.keys(sampleItem).forEach(key => {
                console.log(`  ${key}: ${sampleItem[key]} (${typeof sampleItem[key]})`);
            });
        }
    }
}

// 运行测试
const tester = new ItemPurchaseTester();
tester.runTest().catch(console.error);

module.exports = ItemPurchaseTester;
